home *** CD-ROM | disk | FTP | other *** search
/ 3D GFX / 3D GFX.iso / amiutils / i_l / irit5 / cagd_lib / cagdcoer.c < prev    next >
C/C++ Source or Header  |  1995-12-30  |  20KB  |  438 lines

  1. /******************************************************************************
  2. * CagdCoer.c - Handle point coercesions/conversions.                  *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Aug. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. /*****************************************************************************
  10. * DESCRIPTION:                                                               M
  11. * Coerce Srf/Crv Point from index Index of Points array of Type PType to a   M
  12. * point type E2.                                                             M
  13. *   If however Index < 0 Points is considered single point.                  M
  14. *                                                                            *
  15. * PARAMETERS:                                                                M
  16. *   E2Point:   Where the coerced information is to besaved.                  M
  17. *   Points:    Array of vectors if Index >= 0, a single point if Index < 0.  M
  18. *   Index:     Index into the vectors of Points.                             M
  19. *   PType:     Point type to be expected from Points.                        M
  20. *                                                                            *
  21. * RETURN VALUE:                                                              M
  22. *   void                                                                     M
  23. *                                                                            *
  24. * KEYWORDS:                                                                  M
  25. *   CagdCoerceToE2, coercion                                                 M
  26. *****************************************************************************/
  27. void CagdCoerceToE2(CagdRType *E2Point,
  28.             CagdRType *Points[CAGD_MAX_PT_SIZE],
  29.             int Index,
  30.             CagdPointType PType)
  31. {
  32.     CagdBType
  33.     IsRational = CAGD_IS_RATIONAL_PT(PType);
  34.     int i,
  35.         MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
  36.     CagdRType *Point;
  37.  
  38.     if (MaxCoord > 2)
  39.     MaxCoord = 2;
  40.  
  41.     if (Index < 0) {                  /* Points is one single point. */
  42.         Point = *Points;
  43.     for (i = 1; i <= MaxCoord; i++)
  44.         *E2Point++ = IsRational ? Point[i] / Point[W] : Point[i];
  45.     }
  46.     else                         /* Points is a full arrays from Srf or Crv. */
  47.     for (i = 1; i <= MaxCoord; i++)
  48.         *E2Point++ = IsRational ? Points[i][Index] / Points[W][Index] :
  49.                       Points[i][Index];
  50.  
  51.     for (i = MaxCoord + 1; i <= 2; i++)
  52.     *E2Point++ = 0.0;
  53. }
  54.  
  55. /*****************************************************************************
  56. * DESCRIPTION:                                                               M
  57. * Coerce Srf/Crv Point from index Index of Points array of Type PType to a   M
  58. * point type E3.                                                             M
  59. *   If however Index < 0 Points is considered single point.                  M
  60. *                                                                            *
  61. * PARAMETERS:                                                                M
  62. *   E3Point:   Where the coerced information is to besaved.                  M
  63. *   Points:    Array of vectors if Index >= 0, a single point if Index < 0.  M
  64. *   Index:     Index into the vectors of Points.                             M
  65. *   PType:     Point type to be expected from Points.                        M
  66. *                                                                            *
  67. * RETURN VALUE:                                                              M
  68. *   void                                                                     M
  69. *                                                                            *
  70. * KEYWORDS:                                                                  M
  71. *   CagdCoerceToE3 coercion                                                  M
  72. *****************************************************************************/
  73. void CagdCoerceToE3(CagdRType *E3Point,
  74.             CagdRType *Points[CAGD_MAX_PT_SIZE],
  75.             int Index,
  76.             CagdPointType PType)
  77. {
  78.     CagdBType
  79.     IsRational = CAGD_IS_RATIONAL_PT(PType);
  80.     int i,
  81.     MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
  82.     CagdRType *Point;
  83.  
  84.     if (MaxCoord > 3)
  85.     MaxCoord = 3;
  86.  
  87.     if (Index < 0) {                  /* Points is one single point. */
  88.     Point = *Points;
  89.     for (i = 1; i <= MaxCoord; i++)
  90.         *E3Point++ = IsRational ? Point[i] / Point[W] : Point[i];
  91.     }
  92.     else                         /* Points is a full arrays from Srf or Crv. */
  93.     for (i = 1; i <= MaxCoord; i++)
  94.         *E3Point++ = IsRational ? Points[i][Index] / Points[W][Index] :
  95.                       Points[i][Index];
  96.  
  97.     for (i = MaxCoord + 1; i <= 3; i++)
  98.     *E3Point++ = 0.0;
  99. }
  100.  
  101. /*****************************************************************************
  102. * DESCRIPTION:                                                               M
  103. * Coerce Srf/Crv Point from index Index of Points array of Type PType to a   M
  104. * point type P2.                                                             M
  105. *   If however Index < 0 Points is considered single point.                  M
  106. *                                                                            *
  107. * PARAMETERS:                                                                M
  108. *   P2Point:   Where the coerced information is to besaved.                  M
  109. *   Points:    Array of vectors if Index >= 0, a single point if Index < 0.  M
  110. *   Index:     Index into the vectors of Points.                             M
  111. *   PType:     Point type to be expected from Points.                        M
  112. *                                                                            *
  113. * RETURN VALUE:                                                              M
  114. *   void                                                                     M
  115. *                                                                            *
  116. * KEYWORDS:                                                                  M
  117. *   CagdCoerceToP2, coercion                                                 M
  118. *****************************************************************************/
  119. void CagdCoerceToP2(CagdRType *P2Point,
  120.             CagdRType *Points[CAGD_MAX_PT_SIZE],
  121.             int Index,
  122.             CagdPointType PType)
  123. {
  124.     CagdBType
  125.     IsRational = CAGD_IS_RATIONAL_PT(PType);
  126.     int i,
  127.         MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
  128.     CagdRType *Point;
  129.  
  130.     if (MaxCoord > 2)
  131.     MaxCoord = 2;
  132.  
  133.     if (Index < 0) {                  /* Points is one single point. */
  134.         Point = *Points;
  135.     *P2Point++ = IsRational ? Point[W] : 1.0;
  136.     for (i = 1; i <= MaxCoord; i++)
  137.         *P2Point++ = Point[i];
  138.     }
  139.     else {                       /* Points is a full arrays from Srf or Crv. */
  140.     *P2Point++ = IsRational ? Points[W][Index] : 1.0;
  141.     for (i = 1; i <= MaxCoord; i++)
  142.         *P2Point++ = Points[i][Index];
  143.     }
  144.  
  145.     for (i = MaxCoord + 1; i <= 2; i++)
  146.     *P2Point++ = 0.0;
  147. }
  148.  
  149. /*****************************************************************************
  150. * DESCRIPTION:                                                               M
  151. * Coerce Srf/Crv Point from index Index of Points array of Type PType to a   M
  152. * point type P3.                                                             M
  153. *   If however Index < 0 Points is considered single point.                  M
  154. *                                                                            *
  155. * PARAMETERS:                                                                M
  156. *   P3Point:   Where the coerced information is to besaved.                  M
  157. *   Points:    Array of vectors if Index >= 0, a single point if Index < 0.  M
  158. *   Index:     Index into the vectors of Points.                             M
  159. *   PType:     Point type to be expected from Points.                        M
  160. *                                                                            *
  161. * RETURN VALUE:                                                              M
  162. *   void                                                                     M
  163. *                                                                            *
  164. * KEYWORDS:                                                                  M
  165. *   CagdCoerceToP3, coercion                                                 M
  166. *****************************************************************************/
  167. void CagdCoerceToP3(CagdRType *P3Point,
  168.             CagdRType *Points[CAGD_MAX_PT_SIZE],
  169.             int Index,
  170.             CagdPointType PType)
  171. {
  172.     CagdBType
  173.     IsRational = CAGD_IS_RATIONAL_PT(PType);
  174.     int i,
  175.     MaxCoord = CAGD_NUM_OF_PT_COORD(PType);
  176.     CagdRType *Point;
  177.  
  178.     if (MaxCoord > 3)
  179.     MaxCoord = 3;
  180.  
  181.     if (Index < 0) {                  /* Points is one single point. */
  182.     Point = *Points;
  183.     *P3Point++ = IsRational ? Point[W] : 1.0;
  184.     for (i = 1; i <= MaxCoord; i++)
  185.         *P3Point++ = Point[i];
  186.     }
  187.     else {                       /* Points is a full arrays from Srf or Crv. */
  188.     *P3Point++ = IsRational ? Points[W][Index] : 1.0;
  189.     for (i = 1; i <= MaxCoord; i++)
  190.         *P3Point++ = Points[i][Index];
  191.     }
  192.  
  193.     for (i = MaxCoord + 1; i <= 3; i++)
  194.     *P3Point++ = 0.0;
  195. }
  196.  
  197. /*****************************************************************************
  198. * DESCRIPTION:                                                               M
  199. * Coerces Srf/Crv Point from index Index of Points array of Type PType to a  M
  200. * new type NewPType. If however Index < 0 Points is considered single point. M
  201. *                                                                            *
  202. * PARAMETERS:                                                                M
  203. *   NewPoint:  Where the coerced information is to besaved.                  M
  204. *   NewPType:  Point type of the coerced new point.                          M
  205. *   Points:    Array of vectors if Index >= 0, a single point if Index < 0.  M
  206. *   Index:     Index into the vectors of Points.                             M
  207. *   OldPType:  Point type to be expected from Points.                        M
  208. *                                                                            *
  209. * RETURN VALUE:                                                              M
  210. *   void                                                                     M
  211. *                                                                            *
  212. * KEYWORDS:                                                                  M
  213. *   CagdCoercePointTo, coercion                                              M
  214. *****************************************************************************/
  215. void CagdCoercePointTo(CagdRType *NewPoint,
  216.                CagdPointType NewPType,
  217.                CagdRType *Points[CAGD_MAX_PT_SIZE],
  218.                int Index,
  219.                CagdPointType OldPType)
  220. {
  221.     CagdBType
  222.     IsRational = CAGD_IS_RATIONAL_PT(OldPType),
  223.     NewIsRational = CAGD_IS_RATIONAL_PT(NewPType);
  224.     int i,
  225.     MaxCoord = CAGD_NUM_OF_PT_COORD(OldPType),
  226.     NewMaxCoord = CAGD_NUM_OF_PT_COORD(NewPType);
  227.     CagdRType *Point, Weight;
  228.  
  229.     if (MaxCoord > NewMaxCoord)
  230.     MaxCoord = NewMaxCoord;
  231.  
  232.     if (Index < 0) {                  /* Points is one single point. */
  233.         Point = *Points;
  234.     Weight = IsRational ? Point[W] : 1.0;
  235.     if (NewIsRational) {
  236.         *NewPoint++ = Weight;
  237.         Weight = 1.0;
  238.     }
  239.     for (i = 1; i <= MaxCoord; i++)
  240.         *NewPoint++ = Point[i] / Weight;
  241.     }
  242.     else {                       /* Points is a full arrays from Srf or Crv. */
  243.     Weight = IsRational ? Points[W][Index] : 1.0;
  244.     if (NewIsRational) {
  245.         *NewPoint++ = Weight;
  246.         Weight = 1.0;
  247.     }
  248.     for (i = 1; i <= MaxCoord; i++)
  249.         *NewPoint++ = Points[i][Index] / Weight;
  250.     }
  251.  
  252.     for (i = MaxCoord + 1; i <= NewMaxCoord; i++)
  253.     *NewPoint++ = 0.0;
  254. }
  255.  
  256. /*****************************************************************************
  257. * DESCRIPTION:                                                               M
  258. * Coerces an array of vectors, Points. of point type OldPType to point type  M
  259. * NewPType, in place.                                 M
  260. *                                                                            *
  261. * PARAMETERS:                                                                M
  262. *   Points:    Where the old and new points are placed.                      M
  263. *   Len:       Length of vectors in the array of vectors, Points.            M
  264. *   OldPType:  Point type to be expected from Points.                        M
  265. *   NewPType:  Point type of the coerced new point.                          M
  266. *                                                                            *
  267. * RETURN VALUE:                                                              M
  268. *   void                                                                     M
  269. *                                                                            M
  270. * KEYWORDS:                                                                  M
  271. *   CagdCoercePointsTo, coercion                                             M
  272. *****************************************************************************/
  273. void CagdCoercePointsTo(CagdRType *Points[],
  274.             int Len,
  275.             CagdPointType OldPType,
  276.             CagdPointType NewPType)
  277. {
  278.     int i, j,
  279.     OldIsRational = CAGD_IS_RATIONAL_PT(OldPType),
  280.     OldNumOfCoords = CAGD_NUM_OF_PT_COORD(OldPType),
  281.     NewIsRational = CAGD_IS_RATIONAL_PT(NewPType),
  282.     NewNumOfCoords = CAGD_NUM_OF_PT_COORD(NewPType);
  283.     CagdRType *NewPoints[CAGD_MAX_PT_SIZE], Pt[CAGD_MAX_PT_SIZE];
  284.  
  285.     for (i = !NewIsRational; i <= NewNumOfCoords; i++)
  286.     NewPoints[i] = (CagdRType *) IritMalloc(sizeof(CagdRType) * Len);
  287.  
  288.     for (i = 0; i < Len; i++) {
  289.     CagdCoercePointTo(Pt, NewPType, Points, i, OldPType);
  290.  
  291.     if (NewIsRational)
  292.         for (j = 0; j <= NewNumOfCoords; j++)
  293.         NewPoints[j][i] = Pt[j];
  294.     else
  295.         for (j = 1; j <= NewNumOfCoords; j++)
  296.         NewPoints[j][i] = Pt[j - 1];
  297.     }
  298.  
  299.     /* Replace old rep. with new. */
  300.     for (i = !OldIsRational; i <= OldNumOfCoords; i++)
  301.     IritFree((VoidPtr) Points[i]);
  302.     Points[0] = NULL;
  303.     for (i = !NewIsRational; i <= NewNumOfCoords; i++)
  304.     Points[i] = NewPoints[i];
  305.     for (; i <= CAGD_MAX_PT_COORD; i++)
  306.     Points[i] = NULL;
  307. }
  308.  
  309. /*****************************************************************************
  310. * DESCRIPTION:                                                               M
  311. * Coerces a curve to a new point type PType. If given curve is E1 or P1      M
  312. * and requested new type is E2 or P2 the Y coefficients are updated to       M
  313. * hold the parametric domain of the curve.                                 M
  314. *                                                                            *
  315. * PARAMETERS:                                                                M
  316. *   Crv:       To be coerced to a new point type PType.                      M
  317. *   PType:     New point type for Crv.                                       M
  318. *                                                                            *
  319. * RETURN VALUE:                                                              M
  320. *   CagdCrvStruct *:  The new, coerced to PType, curve.                      M
  321. *                                                                            *
  322. * KEYWORDS:                                                                  M
  323. *   CagdCoerceCrvTo, coercion                                                M
  324. *****************************************************************************/
  325. CagdCrvStruct *CagdCoerceCrvTo(CagdCrvStruct *Crv, CagdPointType PType)
  326. {
  327.     Crv = CagdCrvCopy(Crv);
  328.     CagdCoercePointsTo(Crv -> Points, Crv -> Length, Crv -> PType, PType);
  329.  
  330.     if (CAGD_NUM_OF_PT_COORD(Crv -> PType) == 1 &&
  331.     CAGD_NUM_OF_PT_COORD(PType) == 2) {
  332.     /* Update the parameter space to be the second axis. */
  333.     CagdRType
  334.         *WPts = Crv -> Points[0],
  335.         *Pts = Crv -> Points[2],
  336.         *Nodes = CagdCrvNodes(Crv);
  337.  
  338.     CAGD_GEN_COPY(Pts, Nodes, sizeof(CagdRType) * Crv -> Length);
  339.     if (WPts != NULL) {
  340.         int i;
  341.  
  342.         for (i = 0; i < Crv -> Length; i++)
  343.             *Pts++ *= *WPts++;
  344.     }
  345.  
  346.     IritFree((VoidPtr) Nodes);
  347.     }
  348.  
  349.     Crv -> PType = PType;
  350.  
  351.     return Crv;
  352. }
  353.  
  354. /*****************************************************************************
  355. * DESCRIPTION:                                                               M
  356. * Coerces a surface to a new point type PType. If given surface is E1 or P1  M
  357. * and requested new type is E3 or P3 the Y and Z coefficients are updated to M
  358. * hold the parametric domain of the surface.                                 M
  359. *                                                                            *
  360. * PARAMETERS:                                                                M
  361. *   Srf:       To be coerced to a new point type PType.                      M
  362. *   PType:     New point type for Srf.                                       M
  363. *                                                                            *
  364. * RETURN VALUE:                                                              M
  365. *   CagdSrfStruct *:  The new, coerced to PType, surface.                    M
  366. *                                                                            *
  367. * KEYWORDS:                                                                  M
  368. *   CagdCoerceSrfTo, coercion                                                M
  369. *****************************************************************************/
  370. CagdSrfStruct *CagdCoerceSrfTo(CagdSrfStruct *Srf, CagdPointType PType)
  371. {
  372.     Srf = CagdSrfCopy(Srf);
  373.     CagdCoercePointsTo(Srf -> Points, Srf -> ULength * Srf -> VLength,
  374.                Srf -> PType, PType);
  375.  
  376.     if (CAGD_NUM_OF_PT_COORD(Srf -> PType) == 1 &&
  377.     CAGD_NUM_OF_PT_COORD(PType) == 3) {
  378.     /* Update the parameter space to be the second and third axis. */
  379.     int i;
  380.     CagdRType *PtsY, *PtsZ,
  381.         *WPts = Srf -> Points[0],
  382.         *UNodes = CagdSrfNodes(Srf, CAGD_CONST_U_DIR),
  383.         *VNodes = CagdSrfNodes(Srf, CAGD_CONST_V_DIR);
  384.  
  385.     for (i = 0, PtsY = Srf -> Points[2];
  386.          i < Srf -> VLength;
  387.          i++, PtsY += Srf -> ULength)
  388.         CAGD_GEN_COPY(PtsY, UNodes, sizeof(CagdRType) * Srf -> ULength);
  389.  
  390.     for (i = 0, PtsZ = Srf -> Points[3]; i < Srf -> VLength; i++) {
  391.         int j;
  392.  
  393.         for (j = 0; j < Srf -> ULength; j++)
  394.             *PtsZ++ = VNodes[i];
  395.     }
  396.  
  397.     if (WPts != NULL) {
  398.         PtsY = Srf -> Points[2];
  399.         PtsZ = Srf -> Points[3];
  400.         for (i = 0; i < Srf -> ULength * Srf -> VLength; i++) {
  401.             *PtsY++ *= *WPts;
  402.             *PtsZ++ *= *WPts++;
  403.  
  404.         }
  405.     }
  406.  
  407.     IritFree((VoidPtr) UNodes);
  408.     IritFree((VoidPtr) VNodes);
  409.     }
  410.  
  411.     Srf -> PType = PType;
  412.     return Srf;
  413. }
  414.  
  415. /*****************************************************************************
  416. * DESCRIPTION:                                                               M
  417. * Returns a point type which spans the spaces of both two given point types. M
  418. *                                                                            *
  419. * PARAMETERS:                                                                M
  420. *   PType1, PType2: To point types to find the point type of their union.    M
  421. *                                                                            *
  422. * RETURN VALUE:                                                              M
  423. *   CagdPointType:  A point type of the union of the spaces of PType1 and    M
  424. *                   PType2.                                                  M
  425. *                                                                            *
  426. * KEYWORDS:                                                                  M
  427. *   CagdMergePointType, coercion                                             M
  428. *****************************************************************************/
  429. CagdPointType CagdMergePointType(CagdPointType PType1, CagdPointType PType2)
  430. {
  431.     CagdBType
  432.     IsRational = CAGD_IS_RATIONAL_PT(PType1) || CAGD_IS_RATIONAL_PT(PType2);
  433.     int NumCoords = MAX(CAGD_NUM_OF_PT_COORD(PType1),
  434.                 CAGD_NUM_OF_PT_COORD(PType2));
  435.  
  436.     return CAGD_MAKE_PT_TYPE(IsRational, NumCoords);
  437. }
  438.